<!--
 * @Description: 修改密码
 * @Author: DHL
 * @Date: 2022-04-02 16:09:21
 * @LastEditors: DHL
 * @LastEditTime: 2023-02-15 09:47:42
-->

<template>
  <tw-dialog
    v-model="visible"
    title="修改密码"
    :loading="loading"
    width="600px"
    height="400px"
    @close="handleClose"
  >
    <el-form ref="passwordFormRef" :model="passwordForm" :rules="rules">
      <el-form-item prop="loginName">
        <el-input
          class="area"
          type="text"
          placeholder="请输入登录名"
          v-model="passwordForm.loginName"
          autocomplete="off"
          size="default"
        ></el-input>
      </el-form-item>
      <el-form-item prop="verifyImgCode" class="verify-img-code">
        <el-input
          class="area"
          type="text"
          placeholder="请输入验证码"
          v-model="passwordForm.verifyImgCode"
          autocomplete="off"
          size="default"
        ></el-input>
        <img :src="verifyCode.src" @click="handleSearchVerifyImgCode" />
      </el-form-item>

      <el-form-item prop="phone">
        <el-input
          class="area"
          type="text"
          placeholder="请输入手机号"
          v-model="passwordForm.phone"
          autocomplete="off"
          auto-complete="new-password"
          size="default"
        ></el-input>
      </el-form-item>
      <el-form-item prop="phone" class="verify-phone-code">
        <el-input
          class="area"
          type="text"
          placeholder="请输入验证码"
          v-model="passwordForm.verifyPhoneCode"
          autocomplete="off"
          size="default"
        ></el-input>

        <el-button
          class="phoneVerify"
          type="info"
          plain
          size="default"
          @click="handleSearchVerifyPhoneCode"
          >{{ verifyCode.phoneVerifyText }}</el-button
        >
        <!--        <span
          class="phoneVerify"
          :class="`${verifyCode.phoneVerifyDisable ? 'phoneVerifyDisable' : ''}`"
        >
        </span>-->
      </el-form-item>

      <el-form-item prop="newPassword">
        <el-input
          class="area"
          type="text"
          placeholder="请输入新密码"
          v-model="passwordForm.newPassword"
          autocomplete="off"
          auto-complete="new-password"
          size="default"
        ></el-input>
      </el-form-item>
      <el-form-item prop="confirmPassword">
        <el-input
          class="area"
          type="text"
          placeholder="请输入确认新密码"
          v-model="passwordForm.confirmPassword"
          autocomplete="off"
          auto-complete="new-password"
          size="default"
        ></el-input>
      </el-form-item>
    </el-form>

    <div class="passVerification">
      <div class="pass-verifi">
        <div>弱</div>
        <div class="verifiDiv" :class="dynamicOne"></div>
      </div>
      <div class="pass-verifi">
        <div>中</div>
        <div class="verifiDiv" :class="dynamicTow"></div>
      </div>
      <div class="pass-verifi">
        <div>强</div>
        <div class="verifiDiv" :class="dynamicThs"></div>
      </div>
    </div>

    <div class="passwordTips">
      温馨提示：请输入6~20位密码，并必须包含大小写、数字、特殊字符的其中两种。
    </div>

    <template #footer>
      <el-button @click="handleClose()">取 消</el-button>
      <el-button type="primary" @click="handleSubmit()"> 提 交</el-button>
    </template>
  </tw-dialog>
</template>

<script setup lang="ts">
  import { ElMessage } from 'element-plus'
  import { assign } from 'lodash-es'
  import { reactive, ref, watch } from 'vue'
  import {
    apiUpdateUserPwdByPhone,
    apiUserUpdatePassword,
    apiVerifyGetPhoneCode,
    apiVerifyGetVerifyImgCode
  } from '@/api/system/user'
  import { useLoginUserStore } from '@/store/modules/loginUser'
  import { log } from '../../utils/logUtils'
  import { isEmpty } from '@/utils/isUtils'

  /**
   * 当前登录用户
   */
  const loginUser = useLoginUserStore()

  /**
   * 显示弹框
   */
  const visible = ref(false)

  const loading = ref(false)

  const passwordFormRef = ref()

  /**
   * 密码更新表单
   */
  const passwordForm = reactive({
    loginName: '',
    newPassword: '',
    confirmPassword: '',
    phone: '',
    verifyImgCode: '',
    verifyPhoneCode: ''
  })

  /**
   * 表单校验
   */
  const rules = reactive({
    originalPassword: [
      { required: true, message: '请输入原始密码', trigger: 'blur' },
      { min: 6, max: 20, message: '长度在 6 到 20 个字符', trigger: 'blur' }
    ],
    newPassword: [
      { required: true, message: '请输入修改密码', trigger: 'blur' },
      { min: 6, max: 20, message: '长度在 6 到 20 个字符', trigger: 'blur' }
    ],
    confirmPassword: [
      { required: true, message: '再次输入修改密码', trigger: 'blur' },
      { min: 6, max: 20, message: '长度在 6 到 20 个字符', trigger: 'blur' }
    ]
  })

  // 密码强度
  const dynamicOne = ref('verifiDiv')
  const dynamicTow = ref('verifiDiv')
  const dynamicThs = ref('verifiDiv')

  /**
   * 显示弹框
   */
  function handleOpen() {
    visible.value = true
    handleSearchVerifyImgCode()
  }

  /**
   * 监听密码强度
   */
  watch(
    () => passwordForm.newPassword,
    (newVal: string, oldVal: string) => {
      let modes = 0

      //正则表达式验证符合要求的
      //数字
      if (/\d/.test(newVal)) {
        modes++
      }
      //小写
      if (/[a-z]/.test(newVal)) {
        modes++
      }
      //大写
      if (/[A-Z]/.test(newVal)) {
        modes++
      }
      //特殊字符
      if (/\W/.test(newVal)) {
        modes++
      }

      if (modes == 1) {
        dynamicOne.value = 'verifiDivone'
        dynamicTow.value = 'verifiDiv'
        dynamicThs.value = 'verifiDiv'
      } else if (modes == 2) {
        dynamicOne.value = 'verifiDivone'
        dynamicTow.value = 'verifiDivtow'
        dynamicThs.value = 'verifiDiv'
      } else if (modes > 2) {
        dynamicOne.value = 'verifiDivone'
        dynamicTow.value = 'verifiDivtow'
        dynamicThs.value = 'verifiDivths'
      }
    }
  )

  /**
   * 提交
   */
  function handleSubmit() {
    passwordFormRef.value.validate((valid: boolean) => {
      if (valid) {
        if (dynamicTow.value === 'verifiDiv') {
          ElMessage.warning('密码太简单了')
        } else if (passwordForm.newPassword !== passwordForm.confirmPassword) {
          ElMessage.warning('两次密码不相同')
        } else {
          loading.value = true
          apiUpdateUserPwdByPhone(passwordForm)
            .then((result) => {
              if (result?.success) {
                ElMessage.success(result.message)
                visible.value = false
              } else {
                ElMessage.error(result?.message)
              }
            })
            .finally(() => {
              loading.value = false
            })
        }
      } else {
        log.warn('更新密码', '表单校验失败')
      }
    })
  }

  /**
   * 取消
   */
  function handleClose() {
    visible.value = false
  }

  const verifyCode = reactive({
    unionCode: '',
    src: '',
    phoneVerifyText: '获取验证码',
    phoneVerifyDisable: false
  })

  /**
   * 获取图形验证码
   */
  function handleSearchVerifyImgCode() {
    apiVerifyGetVerifyImgCode(110, 35).then((result) => {
      if (result?.success) {
        nextTick(() => {
          verifyCode.unionCode = result?.data?.unionCode
          verifyCode.src = result?.data?.imgBytes
        })
      }
    })
  }

  /**
   * 获取手机验证码
   */
  function handleSearchVerifyPhoneCode() {
    if (verifyCode.phoneVerifyDisable) {
      return
    }

    if (!validateMobilePhone(passwordForm.phone)) {
      ElMessage.warning('请正确输入手机号码')
      return
    }

    if (isEmpty(passwordForm.verifyImgCode)) {
      ElMessage.warning('请输入图形验证码')
      return
    }

    apiVerifyGetPhoneCode(
      verifyCode.unionCode,
      passwordForm.verifyImgCode,
      passwordForm.phone
    ).then((result) => {
      ElMessage.warning(result?.message)
      if (result?.success) {
        let second = 60
        let timer: any = setInterval(function () {
          if (second > 0) {
            second--
            verifyCode.phoneVerifyText = `${second}s`
            verifyCode.phoneVerifyDisable = true
          } else {
            clearInterval(timer)
            timer = null
            verifyCode.phoneVerifyText = '获取验证码'
            verifyCode.phoneVerifyDisable = false
          }
        }, 1000)
      } else {
        handleSearchVerifyImgCode()
      }
    })
  }

  /**
   * 手机号(mobile phone)中国(宽松), 只要是13,14,15,16,17,18,19开头即可
   */
  function validateMobilePhone(mobilePhone: string) {
    const regex = new RegExp(/^(?:(?:\+|00)86)?1\d{10}$/)
    return regex.test(mobilePhone)
  }

  defineExpose({
    handleOpen
  })
</script>

<style scoped lang="scss">
  :deep(.verify-img-code) {
    .el-form-item__content {
      justify-content: space-between;
      .el-input {
        width: 75%;
      }
      image {
        width: 110px;
        height: 32px;
        background-color: #eeeeee;
      }
    }
  }
  :deep(.verify-phone-code) {
    .el-form-item__content {
      justify-content: space-between;
      .el-input {
        width: 75%;
      }
      .phoneVerify {
        width: 75px;
        &.phoneVerifyDisable {
          color: #999;
        }
      }
    }
  }

  .passVerification {
    display: flex;
    align-items: center;
    height: 28px;
    border-radius: 3px;
    border: 1px solid #e8e8e8;
    padding: 5px;
    z-index: 1;
    background: #fff;
    margin-top: 0.3rem;

    .pass-verifi {
      width: 33.33%;
      text-align: center;
      font-size: 0.7rem;

      .verifi-div {
        width: 100%;
        height: 5px;
        background: #ececec;
      }
    }

    .verifiDiv {
      width: 100%;
      height: 5px;
      margin-top: 5px;
      background: #f4f4f5;

      &.verifiDivone {
        background: #26c747;
      }

      &.verifiDivtow {
        background: #ffc335;
      }

      &.verifiDivths {
        background: #ec7e7e;
      }
    }
  }

  .passwordTips {
    font-size: 0.7rem;
    color: #ff7800;
  }
</style>
